package com.gable.report.util;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.gable.report.common.util.MD5Util;
import com.gable.report.common.util.ReturnResultData;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;

import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * 此类是阿里云上传的辅助类
 * 
 * @author jacky
 *
 */
public class FileUploadUtil {
		
	
	//阿里获取文件的域名  (域名/文件路径/加key通常key就是文件名)
	public static final String REALMNAME = "http://gable-hospital.oss-cn-shanghai.aliyuncs.com";
	//阿里服务器上传文件的服务器
	private static final String ENDPOINT="http://oss-cn-shanghai.aliyuncs.com";
	//连接服务器的keyId
	private static final String ACCESSKEYID="LTAIYokZqmBOpCTo";
	//连接服务器的KeySecret
	private static final String ACCESSKEYSECRET="W80vFHHZDYvxeSXhEgIqoWK0xquUNj";
	//在阿里云的项目文件夹，通常是根目录
	public static final String BUCKETNAME="gable-hospital";
	//上传成功后回调路径
	public static final String callbackUrl = "<yourCallbackServerUrl>";

	public static String AccessAddress;

	public static String IsLocalUpload;

	public static String ALFILEURL;

	public static OSSClient ossClient = null;

	public static String FileService;

	public static  void getAccessAddress(){
		ResourceBundle resource = ResourceBundle.getBundle("application");
		 AccessAddress = resource.getString("AccessAddress");
		 IsLocalUpload = resource.getString("IsLocalUpload");
		ALFILEURL = resource.getString("ALFILEURL");
		FileService = resource.getString("FileService");
	}
	
	/**
	 * 上传图片
	 * @return
	 */
	public static boolean fileUpload(byte[] bytes, String key, long fileSize){
		getAccessAddress();
		if(IsLocalUpload.equals("true")){
			boolean bl = send(key,bytes,fileSize);
			return bl;
		}

		OSSClient ossClient = getOssClient();
		ByteArrayInputStream  byteArrayInputStream= null;
		try {
			boolean bl = ossClient.doesBucketExist(BUCKETNAME);
			if(!bl){
				ossClient.createBucket(BUCKETNAME);
			}
			byteArrayInputStream= new ByteArrayInputStream(bytes);
			ossClient.putObject(BUCKETNAME,key,byteArrayInputStream);
			
			if(ExistObject(key)){
				return true;
			}
			
			} catch (Exception e){
				e.printStackTrace();
			}finally {
				try {
					if(byteArrayInputStream != null){
						byteArrayInputStream.close();
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
				ossClient.shutdown();
			}
			
			return false;
	}
	
	/**
	 * 判断当前文件是否存在
	 * @param key
	 * @return
	 */
	public static boolean ExistObject(String key){
		boolean bl = true;
		ossClient = getOssClient();
		bl = ossClient.doesObjectExist(BUCKETNAME, key);
		ossClient.shutdown();
		return bl;
	}
	
	/**
	 * 实例化上传对象
	 * @return
	 */
	public static OSSClient  getOssClient(){
			ossClient = new OSSClient(ENDPOINT,ACCESSKEYID,ACCESSKEYSECRET);
		return ossClient;
	}
	
	/**
	 * 根据key获取文件对象
	 * @param key
	 * @return
	 * @throws IOException 
	 */
	public static OSSObject  getOSSObject (String key){
		OSSClient ossClient = getOssClient();
		OSSObject ossObject = ossClient.getObject(BUCKETNAME,key);
		ossClient.shutdown();
		return ossObject;
	}
	
	
	public static final byte[] input2byte(InputStream inStream)  
            throws IOException {  
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();  
        byte[] buff = new byte[100];  
        int rc = 0;  
        while ((rc = inStream.read(buff, 0, 100)) > 0) {  
            swapStream.write(buff, 0, rc);  
        }  
        byte[] in2b = swapStream.toByteArray();  
        return in2b;  
    }


	public static boolean send(String url,byte [] bytes,long fileSize){
		InputStream in =null;
		try {
			//fileExists(url);
			String strByte = "";
			in = new ByteArrayInputStream(bytes);
			//InputStream in = new FileInputStream(file);
			int length = 102400;
			boolean bl = true;
			byte b[] = new byte[length];
			int streamNum = (int) Math.floor(fileSize / length);
			int leave = (int) fileSize % length;
			for (int i = 0; i < streamNum; i++) {    //当没有读取完时，继续读取
				in.read(b, 0, length);
				//strByte += new String(b, "ISO-8859-1");
				bl = sendPost(b,url);
				if (bl == false) {
					return false;
				}
				System.out.println("i===================" + i);
			}
			if (leave > 0) {
				b = new byte[leave];
				in.read(b, 0, leave);
				//strByte += new String(b, "ISO-8859-1");
				sendPost(b,url);
			}

		}catch (Exception e){
			e.getStackTrace();
		}finally {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return true;
	}



	public static final String ROOTURL = "gable/";

	public static final String PASSWORD = "12345678";

	/**
	 * 判断文件夹是否存在，不存在添加。
	 *
	 * @param url
	 */
	public static void fileExists(String url) {
		if (url == null || url.equals("")) {
			return;
		}

		File file = new File("D:/" + ROOTURL);
		if (!file.exists()) {
			file.mkdir();
		}

		String[] strs = url.split("/");
		String urlInfo = "";
		for (String s : strs) {
			urlInfo = urlInfo + "/" + s;
			File files = new File("D:/" + ROOTURL + urlInfo);
			if (!files.exists()) {
				files.mkdir();
			}
		}
	}

	/**
	 * java模拟post请求去访问文件服务器
	 * @param
	 * @return
	 */
	public static boolean sendPost(byte [] b,String url){
		HttpClient client = new HttpClient();
		PostMethod method =null;
		String RESULTURL = AccessAddress+"/FileUpload/fileInfo";
		try{
			method = new PostMethod(RESULTURL);
			method.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
			Map headMap = headerMap();
			method.setRequestHeader("token", headMap.get("token").toString());
			method.setRequestHeader("timestamp", headMap.get("timestamp").toString() );
			method.setRequestHeader("checksum", headMap.get("checksum").toString() );
			method.addParameter("urls", url);
			//fileInfo = encryptString(fileInfo);
			method.addParameter("fileInfo", new String(b,"ISO-8859-1"));
			//method.setParameter("fileInfo", fileInfo);
			HttpMethodParams param = method.getParams();
			param.setContentCharset("UTF-8");
			int resultCode = client.executeMethod(method);
			if(resultCode != 200){
				return false;
			}
			String result = readStream(method.getResponseBodyAsStream(), "UTF-8");
			ReturnResultData rru = JSON.parseObject(result, ReturnResultData.class);
			if(rru.getResultCode() == 1){
				return true;
			}
			System.out.println("result===============" + result);
		}catch(Exception e){
			e.printStackTrace();
			return false;
		}
		return false;
	}

	//加载头部分信息签名验证，
	public static Map<String,String> headerMap (){
		Map<String,String> map = new HashMap<String,String>();
		long time = new Date().getTime();
		String token = "authority";
		map.put("token", token);
		map.put("timestamp", time+"");
		String checkSum = MD5Util.md5(token+time);
		map.put("checksum", checkSum);
		return map;
	}

	/**
	 * 将传递参数dec加密转base64传递
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static String encryptString(String str) throws Exception{
		//long time1 = new Date().getTime();
		//System.out.println("加密开始============= "+ time1);
		//byte[] result = DES.encrypt(str.getBytes("ISO-8859-1"),PASSWORD);
		String resultString =  org.apache.commons.codec.binary.Base64.encodeBase64String(str.getBytes("ISO-8859-1"));
		//String resultString = MD5Util.md5(str);
		//System.out.println("加密后："+resultString);
		//long time2 = new Date().getTime();
		//System.out.println("完成加密时间===========" + (time2-time1));
		return resultString;
	}


	/**
	 * 读取返回结果
	 * @param in
	 * @param charset
	 * @return
	 * @throws IOException
	 */
	public static String readStream(InputStream in, String charset) throws IOException {
		StringBuilder buf = new StringBuilder();
		int ch = -1;
		Reader reader = new InputStreamReader(new BufferedInputStream(in), charset);
		while (-1 != (ch = reader.read())) {
			buf.append((char) ch);
		}
		return buf.toString();
	}
}
